﻿using System.Reflection;
using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate.Cache;
using NHibernate.Cfg;
using NHibernate.Sidekick.ConsoleTests.Domain.Entities;
using NHibernate.Sidekick.Services.Data;
using NHibernate.Sidekick.Utils.MappingConventions;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Validator.Engine;

namespace NHibernate.Sidekick.ConsoleTests.Setup
{
    static class NHibernate
    {
        public static void Initialize(string dbFile)
        {
            var cfg = Fluently.Configure()
                #region SQLite Configuration
                .ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate") 
                .Database(SQLiteConfiguration.Standard.UsingFile(dbFile)
                /*.Cache(c => c.ProviderClass<HashtableCacheProvider>().UseQueryCache())*/)
                #endregion
                #region MySQL Configuration
                //.Database(MySQLConfiguration.Standard.ConnectionString(c =>
                //    c.Database("dieta").Server("localhost")
                //    .Username("dieta").Password("dieta"))) 
                #endregion
                #region Oracle 10 Configuration
                //.Database(OracleClientConfiguration.Oracle10.ConnectionString(c =>
                //    c.Server("localhost")
                //    .Port(1521)
                //    .Username("test")
                //    .Password("test")
                //    .Pooling(true)
                //    )) 
                #endregion

                .Mappings(m => m.AutoMappings.Add(AutoMap.Assemblies(Assembly.GetExecutingAssembly())
                                                      .Where(a => a.Namespace == typeof (Product).Namespace)
                                                      .Conventions.Add<ForeignKeyConvention>()
                                                      .Conventions.Add<CamelCaseToUnderscoreNamingConvention>()
                                                      .Conventions.Add<ManyToManyTableNamingConvention>()
                                                      .Conventions.Add<CascadeAllConvention>())
                                   )
                .ExposeConfiguration(configuration =>
                                         {
                                             configuration.SetProperty(Environment.Hbm2ddlKeyWords, "auto-quote");
                                             //ConfigureNHibernateValidator(configuration);

                                             // Comment to disable schema generation
                                             BuildDatabaseSchema(configuration, dbFile);
                                         });

            NSession.SetSessionFactory(cfg, null);
        }

        private static void ConfigureNHibernateValidator(Configuration configuration)
        {
            var nhvc = new Validator.Cfg.XmlConfiguration();
            nhvc.Mappings.Add(new Validator.Cfg.MappingConfiguration(Assembly.GetAssembly(typeof(Program)).FullName, null));

            var validator = new ValidatorEngine();
            validator.Configure(nhvc);

            //Registering of Listeners and DDL-applying here
            Validator.Cfg.ValidatorInitializer.Initialize(configuration, validator);
        }

        private static void BuildDatabaseSchema(Configuration configuration, string dbFile)
        {
            // this NHibernate tool takes a configuration (with mapping info in)
            // and exports a database schema from it
            var schemaExport = new SchemaExport(configuration);
            schemaExport.SetOutputFile("SqlScript.sql");
            schemaExport.Create(false, true);
        }
    }
}